package com.kongjs.online.preview.utils;

import com.deepoove.poi.xwpf.NiceXWPFDocument;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

public class PoiUtils {
    public static void merge(List<Path> paths, Path out) {
        List<NiceXWPFDocument> docxs = new ArrayList<>();
        for (int i = 1; i < paths.size(); i++) {
            Path path = paths.get(i);
            NiceXWPFDocument docx = getDocx(path);
            docxs.add(docx);
        }
        NiceXWPFDocument docx = docxs.get(0);
        try (OutputStream outputStream = Files.newOutputStream(out)) {
            merge(docx, docxs, outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void merge(Path dir, Path out) {
        List<NiceXWPFDocument> docxs = new ArrayList<>();
        try (Stream<Path> pathStream = Files.list(dir)) {
            pathStream.forEach(path -> {
                if (Files.isRegularFile(path)) {
                    NiceXWPFDocument docx = getDocx(path);
                    docxs.add(docx);
                }
            });
            Path tempFilePath = Files.createTempFile(dir.toString(), UUID.randomUUID() + ".docx");
            NiceXWPFDocument docx = getDocx(tempFilePath);
            try (OutputStream outputStream = Files.newOutputStream(out)) {
                merge(docx, docxs, outputStream);
            }
            Files.deleteIfExists(tempFilePath);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static NiceXWPFDocument getDocx(Path path) {
        NiceXWPFDocument document;
        try (InputStream in = (Files.newInputStream(path))) {
            document = new NiceXWPFDocument(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return document;
    }

    public static void merge(NiceXWPFDocument docx, List<NiceXWPFDocument> docxs, OutputStream outputStream) {
        try (NiceXWPFDocument document = docx.merge(docxs, docx.createParagraph().createRun())) {
            try (BufferedOutputStream bos = new BufferedOutputStream(outputStream)) {
                document.write(bos);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
